home *** CD-ROM | disk | FTP | other *** search
-
- /************************************************************
-
- generic timed init.c
-
-
- Copyright © 1993, Gregory Babior
- All Rights Reserved
-
- BE WARNED - used as is this init will put up an alert every
- ten seconds until you hold down the command key while dismissing
- the alert.
-
- This is a generic timed init that makes use of the Time
- Manager and the Notification Manager. It uses both in this
- way:
-
- 1) It queues up a delayed call to the Time Manager.
-
- 2) Because the Time Manager is called a interrupt time and
- we want to perform a task which involves moving memory (not
- allowed at interrupt time) the only thing our call does is
- to queue up a call to the Notification Manager, which will
- execute during GetNextEvent/WaitNextEvent time, allowing us
- to do what we will.
-
- 3) When we have completed our task (through using the response
- routine allowed in a Notification record), we queue up another
- call to the Time Manager which, when executed, will queue up
- the same Notification record, which at its end calls the Time
- Manager - etc.etc.etc.
-
- BE WARNED - used as is this init will put up an alert every
- ten seconds until you hold down the command key while dismissing
- the alert.
-
-
- This was my first init and I'm trying to save folks the hell
- I went through in figuring it out. I'm sure there are ways
- to optimize the code and if anyone can make improvements,
- in the code or in the commented documentation, please do so
- and pass them on. Lord knows there is a dearth of info about
- the structure and execution of inits.
-
- ************************************************************/
-
- #include "SetUpA4.h"
- #include "GestaltEqu.h"
- #include "Aliases.h"
- #include "Timer.h"
- #include "Folders.h"
- #include "Notification.h"
-
- struct NMRec theNoteRec;
-
- typedef struct /* Time Manager information record */
- {
- TMTask atmTask; /* original and revised TMtask record */
- long tmRefCon; /* space to pass address of A4 world */
- } TMInfo;
-
- typedef TMInfo *TMInfoPtr;
-
- pascal TMInfoPtr GetTMInfo (void) /* recover address of Time Manager information record */
- = 0x2E89; /* MOVE.L A1,(SP) */
-
- TMInfo myTMInfo; /* a TM information record */
-
-
- pascal void DoTheJob(theNoteRecPtr)
- NMRecPtr theNoteRecPtr;
- {
- OSErr theErr;
- short foundVRefNum;
- long foundDirID;
- FSSpec newSpec;
- short initRefNum;
- long myA4;
- short oldResFile;
- EventRecord theEvent;
- oldResFile = CurResFile(); /* store current resource file id */
-
- asm /* Push all registers because I'm either paranoid or careful */
- {
- move.l d0, -(sp)
- move.l d1, -(sp)
- move.l d2, -(sp)
- move.l d3, -(sp)
- move.l d4, -(sp)
- move.l d5, -(sp)
- move.l d6, -(sp)
- move.l d7, -(sp)
-
- move.l a0, -(sp)
- move.l a1, -(sp)
- move.l a2, -(sp)
- move.l a3, -(sp)
- move.l a4, -(sp)
- move.l a5, -(sp)
- move.l a6, -(sp)
- move.l a7, -(sp)
- }
-
- myA4 = theNoteRecPtr->nmRefCon; /* recall ptr to A4 address which was stored a boot time */
- asm
- {
- move.l myA4, a0; /* Get ptr into A0 */
- }
- RememberA0();
- SetUpA4();
-
- /**********************************************************************************
- here we are going to locate the file that contains the resources we want to use
- (in this case it is the init file itself), access the file, do the work, and
- restore the reference number for the original resource (saved above) as the
- current resource. NOTE - the code uses the name of the file to find it so
- changing the name will cause problems.
- ***********************************************************************************/
-
- theErr = FindFolder(kOnSystemDisk,'extn',kDontCreateFolder,&foundVRefNum,&foundDirID);
- theErr = FSMakeFSSpec(foundVRefNum,foundDirID,"\pgeneric init",&newSpec);
-
- if(theErr == 0)
- {
- initRefNum = FSpOpenResFile(&newSpec,fsRdWrShPerm);
-
- if (initRefNum != -1) /* if we have a valid resource file */
- {
- UseResFile(initRefNum);
- Alert(128,nil); /* do the job now (could do whatever) */
- UseResFile(oldResFile); /* restore original resource file id */
- CloseResFile(initRefNum);
- }
- }
- theErr = NMRemove(theNoteRecPtr);
-
- GetNextEvent(everyEvent,&theEvent);
-
- /***********************************************************************************
- if command key is down, do nothing. This breaks the calling loop. The code
- will do nothing from here on out. If it's not down, activate the next Time
- Manager call.
- ***********************************************************************************/
-
- if(theEvent.modifiers & cmdKey)
- ;
- else
- PrimeTime( (QElemPtr) &myTMInfo, (10000) ); /* activate the next record */
- /* delay of 10 sec */
-
- RestoreA4(); /* restore original A4 */
-
- asm /* Pop all stored data and restore environment */
- {
- move.l (sp)+, a7
- move.l (sp)+, a6
- move.l (sp)+, a5
- move.l (sp)+, a4
- move.l (sp)+, a3
- move.l (sp)+, a2
- move.l (sp)+, a1
- move.l (sp)+, a0
-
- move.l (sp)+, d7
- move.l (sp)+, d6
- move.l (sp)+, d5
- move.l (sp)+, d4
- move.l (sp)+, d3
- move.l (sp)+, d2
- move.l (sp)+, d1
- move.l (sp)+, d0
- }
- }
-
-
-
- pascal void TheTask() /* Yikes - look out - it's interrupt time */
- {
-
- OSErr theErr;
- TMInfoPtr recPtr;
- long myA4;
-
-
- asm /* Push all registers because I'm either paranoid or careful */
- {
- move.l d0, -(sp)
- move.l d1, -(sp)
- move.l d2, -(sp)
- move.l d3, -(sp)
- move.l d4, -(sp)
- move.l d5, -(sp)
- move.l d6, -(sp)
- move.l d7, -(sp)
-
- move.l a0, -(sp)
- move.l a1, -(sp)
- move.l a2, -(sp)
- move.l a3, -(sp)
- move.l a4, -(sp)
- move.l a5, -(sp)
- move.l a6, -(sp)
- move.l a7, -(sp)
- }
-
-
- recPtr = GetTMInfo(); /* get the address to the Time Manager record */
-
- myA4 = recPtr->tmRefCon; /* recall ptr to A4 address which was stored a boot time */
- asm
- {
- move.l myA4, a0; /* Get ptr to A0 */
- }
- RememberA0();
- SetUpA4();
-
- theErr = NMInstall(&theNoteRec);
-
-
- RestoreA4(); /* restore original A4 */
-
- asm /* Pop all stored data and restore environment */
- {
- move.l (sp)+, a7
- move.l (sp)+, a6
- move.l (sp)+, a5
- move.l (sp)+, a4
- move.l (sp)+, a3
- move.l (sp)+, a2
- move.l (sp)+, a1
- move.l (sp)+, a0
-
- move.l (sp)+, d7
- move.l (sp)+, d6
- move.l (sp)+, d5
- move.l (sp)+, d4
- move.l (sp)+, d3
- move.l (sp)+, d2
- move.l (sp)+, d1
- move.l (sp)+, d0
- }
- }
-
-
-
- InstallTMTask(initHndl)
- Handle initHndl;
- {
- myTMInfo.atmTask.tmAddr = TheTask; /* get address of task */
- myTMInfo.atmTask.tmWakeUp = 0; /* initialize tmWakeUp */
- myTMInfo.atmTask.tmReserved = 0; /* initialize tmReserved */
- myTMInfo.tmRefCon = (long)*initHndl; /* store address of A4 */
-
- InsTime((QElemPtr) &myTMInfo); /* install the 1st record */
- PrimeTime((QElemPtr) &myTMInfo, (10000)); /* activate the 1st record */
- } /* delay of 10 sec */
-
- main()
- {
- Ptr initPtr;
- Handle initHndl;
- long theResponse;
- OSErr theErr;
-
- asm
- {
- move.l a0,initPtr; /* Get the pointer to this code */
- }
- RememberA0();
- SetUpA4();
-
- initHndl = RecoverHandle(initPtr);
- HLock(initHndl);
- DetachResource(initHndl); /* leave code in system heap */
- HNoPurge(initHndl); /* make sure it stays there */
-
-
- theErr = Gestalt('sysv',&theResponse);
- if (theResponse < 0x0700) /* if less than system 7 do nothing */
- {
- ;
- }
- else
- {
- /***********************************************************************
- Set up the notification record. This is being used so that we can
- call a routine (DoTheJob) and have actions occur that are not allowed
- at interrupt time.
- ************************************************************************/
-
- theNoteRec.qType = 8;
- theNoteRec.nmMark = 0;
- theNoteRec.nmIcon = nil; /* We want no fireworks */
- theNoteRec.nmSound = nil; /* from the Notification Manager, */
- theNoteRec.nmStr = nil; /* we just want the routine */
- theNoteRec.nmResp = (NMProcPtr)DoTheJob; /* "DoTheJob" to execute. */
- theNoteRec.nmRefCon = (long)*initHndl; /* Store pointer to boot time A4 */
-
- InstallTMTask(initHndl); /* go install first task */
- }
-
- RestoreA4();
- }
-
-
-